<?php

class Kd_Aop_Observer {

    static public $INVOKE_BEFORE = 'INVOKE_BEFORE';
    static public $INVOKE_AFTER = 'INVOKE_AFTER';

    static public function notify($position, $object, $method, $argyments = NULL){
        $class = get_class($object);
        foreach(Kd_Aop_Manager::getListeners() as $listener){
            if(preg_match("/{$listener->getClassMatcher}/i", $class)){
                if($listener->getMethodMatcher()){
                    if(preg_match("/{$listener->getMethodMatcher()}/i", $method)){
                        self::invokePerformer($listener->getPerformer(), $position, $object, $method, $argyments);
                    }
                }else{
                    self::invokePerformer($listener->getPerformer(), $position, $object, $method, $argyments);
                }
            }
        }
    }

    static private function invokePerformer($performer, $position, $object, $method, $argyments){
        if(strpos($performer, '::')){
            $arr = explode('::', $performer);
            return call_user_func_array(
                        array($arr[0], $arr[1]),
                        array($position, $object, $method, $argyments)
                   );
        }elseif(strpos($performer, ':')){
            $arr = explode(':', $performer);
            $class = Kd_Factory::getSingleton($arr[0]);
            return call_user_func_array(
                        array($class, $arr[1]),
                        array($position, $object, $method, $argyments)
                   );
        }else{
            $arr = explode('->', $performer);
            $class = $arr[0];
            return call_user_func_array(
                        array($class, $arr[1]),
                        array($position, $object, $method, $argyments)
                   );
        }
    }
}